package com.benjaminwan.read.free.utils

import android.annotation.SuppressLint
import android.content.Context
import android.text.InputFilter
import android.text.InputType
import androidx.annotation.IntRange
import androidx.annotation.StringRes
import com.benjaminwan.read.free.R
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xui.widget.textview.supertextview.SuperTextView

@SuppressLint("Range")
fun Context.baseTextInputDialog(
    title: String, hint: String, preFill: String, content: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    inputType: Int = InputType.TYPE_CLASS_TEXT,
    filter: Array<InputFilter>? = null,
    neutralText: String,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val allowEmpty = minLength == 0
    val dialogBuilder = MaterialDialog.Builder(this)
        .iconRes(R.drawable.ic_text_fields_black_24dp)
        .title(title)
        .inputType(inputType)
        .input(hint, preFill, allowEmpty, { dialog, input -> })
        .inputRange(minLength, maxLength)
        .alwaysCallInputCallback()
        .positiveText(R.string.dialog_positive)
        .negativeText(R.string.dialog_negative)
        .onNegative { dialog, which -> dialog.dismiss() }
        .onPositive(positiveListener)
        .cancelable(true)
        .autoDismiss(false)

    if (neutralText.isNotEmpty()) {
        dialogBuilder.neutralText(neutralText)
    }
    if (neutralListener != null) {
        dialogBuilder.onNeutral(neutralListener)
    }
    if (content.isNotEmpty()) {
        dialogBuilder.content(content)
    }

    val dialog = dialogBuilder.build()

    if (filter != null) {
        dialog.inputEditText?.filters = filter
    }
    return dialog
}

fun Context.showTextInputDialog(
    title: String, hint: String, preFill: String, content: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null,
    neutralText: String,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val dialog = baseTextInputDialog(
        title, hint, preFill, content,
        minLength, maxLength, InputType.TYPE_CLASS_TEXT,
        filter, neutralText, neutralListener, positiveListener
    )
    dialog.show()
    return dialog
}

fun SuperTextView.showRightTextInputDialog(
    title: String, content: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val hint = getString(R.string.hint_please_input) + title
    val preFill = this.rightString
    val dialog = this.context.baseTextInputDialog(
        title, hint, preFill, content,
        minLength, maxLength, InputType.TYPE_CLASS_TEXT, filter,
        getString(R.string.dialog_neutral), neutralListener, positiveListener
    )
    dialog.show()
    return dialog
}

fun SuperTextView.showRightTextInputDialog(
    title: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog = showRightTextInputDialog(
    title,
    "",
    minLength,
    maxLength,
    filter,
    neutralListener,
    positiveListener
)

fun SuperTextView.showLeftTextInputDialog(
    title: String, content: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val hint = getString(R.string.hint_please_input) + title
    val preFill = this.leftString
    val dialog = this.context.baseTextInputDialog(
        title, hint, preFill, "",
        minLength, maxLength, InputType.TYPE_CLASS_TEXT,
        filter, getString(R.string.dialog_neutral), neutralListener, positiveListener
    )
    dialog.show()
    return dialog
}

fun SuperTextView.showLeftTextInputDialog(
    title: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
) = showLeftTextInputDialog(
    title,
    "",
    minLength,
    maxLength,
    filter,
    neutralListener,
    positiveListener
)

fun Context.showPasswordInputDialog(
    title: String, hint: String, preFill: String,
    @IntRange(from = 0, to = Int.MAX_VALUE.toLong()) minLength: Int,
    @IntRange(from = -1, to = Int.MAX_VALUE.toLong()) maxLength: Int,
    filter: Array<InputFilter>? = null, neutralText: String,
    neutralListener: ((dialog: MaterialDialog, which: DialogAction) -> Unit)?,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val dialog = baseTextInputDialog(
        title, hint, preFill, "",
        minLength, maxLength, InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD,
        filter, neutralText, neutralListener, positiveListener
    )
    dialog.show()
    return dialog
}

fun Context.showFileNameInputDialog(
    @StringRes titleId: Int,
    @StringRes hintId: Int, preFill: String,
    positiveListener: (dialog: MaterialDialog, which: DialogAction) -> Unit,
    neutralListener: (dialog: MaterialDialog, which: DialogAction) -> Unit
): MaterialDialog {
    val hint = getString(hintId)
    return MaterialDialog.Builder(this)
        .iconRes(R.drawable.ic_edit_24)
        .title(titleId)
        .inputType(InputType.TYPE_CLASS_TEXT)
        .input(hint, preFill, true) { dialog, input ->
            input.matches(Regex("[^/\\\\<>*?|\"]+")).takeIf { !it }?.apply {
                dialog.inputEditText?.error = getString(R.string.dialog_file_name_error_hint)
            }
        }
        .inputRange(1, 32)
        .alwaysCallInputCallback()
        .positiveText(R.string.dialog_positive)
        .negativeText(R.string.dialog_negative)
        .neutralText(R.string.dialog_neutral)
        .onNegative { dialog, which -> dialog.dismiss() }
        .onPositive(positiveListener)
        .onNeutral(neutralListener)
        .cancelable(false)
        .autoDismiss(false)
        .show()
}